/*
 * @Description: 双向队列
 * @Autor: wangxin
 * @Date: 2020-06-09 15:19:11
 * @LastEditors: Seven
 * @LastEditTime: 2020-06-10 10:45:26
 */
class Deque {
  constructor() {
    this.count = 0
    this.lowestCount = 0
    this.items = {}
  }
  /* 前端添加元素 */
  addFront(element) {
    // 1.队列为空
    if (this.isEmpty()) {
      this.addBack(element)
    } else if (this.lowestCount > 0) {
      // 2.队列已经删除过第一个元素
      this.lowestCount -= 1
      this.items[this.lowestCount] = element
    } else if (this.lowestCount === 0) {
      // 3.队列没有删除过元素
      for (let i = this.count; i > 0; i--) {
        this.items[i] = this.items[i - 1] // 所有元素后移一位
      }
      this.count += 1
      this.lowestCount = 0
      this.items[this.lowestCount] = element
    }
  }

  /* 后端添加元素 */
  addBack(element) {
    this.items[this.count] = element
    this.count += 1
  }

  /* 移除第一个元素 */
  removeFront() {
    if (this.isEmpty()) {
      return undefined
    }
    const result = this.items[this.lowestCount]
    delete this.items[this.lowestCount]
    this.lowestCount += 1
    return result
  }

  /* 移除最后一个元素 */
  removeBack() {
    if (this.isEmpty()) {
      return undefined
    }
    const result = this.items[this.count - 1]
    delete this.items[this.count - 1]
    this.count -= 1
    return result
  }

  /* 返回第一个元素 */
  peekFront() {
    if (this.isEmpty()) {
      return undefined
    }
    return this.items[this.lowestCount]
  }
  /* 返回最后一个元素 */
  peekBack() {
    if (this.isEmpty()) {
      return undefined
    }
    return this.items[this.count - 1]
  }

  isEmpty() {
    return this.count === 0
  }

  size() {
    return this.count - this.lowestCount
  }

  clear() {
    this.count = 0
    this.lowestCount = 0
    this.items = {}
  }

  toString() {
    if (this.isEmpty()) {
      return ''
    }
    let str = `${this.items[this.lowestCount]}`
    for (let i = this.lowestCount + 1; i < this.count; i++) {
      str = `${str},${this.items[i]}`
    }
    return str
  }
}

// 代码测试
// var deque = new Deque()
// deque.addBack(1)
// deque.addBack(2)
// deque.addBack(3)
// console.log(deque.removeFront())
